import { create } from 'zustand'
import { videoService } from '@/services'
import { useFetch } from '@/hooks/useFetch'
import { useLoadingStore } from '@/stores/loading-store'
import { toast } from '@/hooks/use-toast'
import { type CloseToneStore } from '@/services'
import { sleep } from '@/lib/utils'

// 轮询次数
const POLLING_TIMES = 1800 // 1小时
export interface Option {
  label: string
  value: string
  label_zh?: string
}

// 定义状态接口
interface SystemConfig {
  language: Option[]
  character: Option[]
}

interface RegionItem {
  zh_name: string
  id: string | number
}

export interface AudioDataItem {
  id: number
  label: string
  value: number
  file_id: string
  file_url: string
  voice_id?: string
}

interface VideoState {
  videoStatusInfo: string // 生成视频状态文字
  resText: string // 口播文案
  // 系统配置
  systemConfig: SystemConfig | null
  // 热点区域列表
  regionList: Option[]
  // 音色列表
  toneList: AudioDataItem[] // 根据实际类型定义
  // 热点话题列表
  hotTopicList: Option[]
  // loading 状态
  loading: boolean
  // 错误状态
  error: Error | null
  setResText: (resText: string) => void
  // actions
  fetchSystemConfig: () => Promise<void>
  fetchRegionList: () => Promise<void>
  fetchToneList: (refresh?: boolean) => Promise<void>
  cloneStore: (option: {
    names: { zh: string; en: string }
    url: string
  }) => Promise<CloseToneStore | undefined>
  fetchHotTopicList: (value: string) => Promise<void>
  getBroadcastDetail: (value: string, isRefresh?: boolean) => Promise<string>
  getAudioVideoDetail: (value: string) => Promise<string>
}

// 定义缓存对象
const hotTopicCache: { [key: string]: Option[] } = {}

// 创建 store
export const useVideoStore = create<VideoState>()((set, get) => ({
  videoStatusInfo: '',
  resText: '',
  systemConfig: null,
  regionList: [],
  toneList: [],
  hotTopicList: [],
  loading: false,
  error: null,

  setResText: (resText: string) => set({ resText }),

  // 获取系统配置
  fetchSystemConfig: async () => {
    try {
      set({ loading: true, error: null })
      const res = await videoService.getSystemConfig()
      set({
        systemConfig: {
          language: res.language,
          character: res.character,
        },
        loading: false,
      })
    } catch (error) {
      set({ error: error as Error, loading: false })
    }
  },

  // 获取热点区域列表
  fetchRegionList: async () => {
    try {
      set({ loading: true, error: null })
      const res = await videoService.getHotTopicAreaList()
      set({
        regionList: res.map((item: RegionItem) => ({
          label: item.zh_name,
          value: String(item.id),
        })),
        loading: false,
      })
    } catch (error) {
      set({ error: error as Error, loading: false })
    }
  },

  // 获取音色列表
  fetchToneList: async (refresh: boolean = false) => {
    try {
      set({ loading: true, error: null })

      // 获取当前的 toneList
      if (!refresh && get().toneList.length > 0) return

      const res = await videoService.getToneList()
      set({
        toneList: res.map((item) => {
          return {
            id: item.id,
            label: item.names.zh,
            value: item.id,
            file_id: item.file_id,
            file_url: item.file_url,
            voice_id: item.voice_id,
          }
        }),
        loading: false,
      })
    } catch (error) {
      set({ error: error as Error, loading: false })
    }
  },

  // 克隆音色
  cloneStore: async (option: {
    names: { zh: string; en: string }
    url: string
  }): Promise<CloseToneStore | undefined> => {
    try {
      set({ loading: true, error: null })
      const { names, url } = option
      const res = await videoService.createToneStore(names, url)
      console.log('🚀 ~ cloneStore: ~ res:', res)
      set({
        loading: false,
      })
      return res
    } catch (error) {
      set({ error: error as Error, loading: false })
    }
  },

  // 获取热点话题列表
  fetchHotTopicList: async (value: string) => {
    try {
      set({ loading: true, error: null })

      // 检查缓存中是否已有数据
      if (hotTopicCache[value]) {
        set({
          hotTopicList: hotTopicCache[value],
          loading: false,
        })
        return
      }
      const res = await videoService.getHotTopicList(value)
      const hotTopicList: Option[] = res.map((item) => ({
        label: `${item.word}(${item.zh_word}) (${item.score})`,
        label_zh: item.zh_word,
        value: item.id + '',
      }))

      // 缓存数据
      hotTopicCache[value] = hotTopicList

      set({
        hotTopicList,
        loading: false,
      })
    } catch (error) {
      set({ error: error as Error, loading: false })
    }
  },
  // 轮询获取文案任务详情
  getBroadcastDetail: async (
    id: string,
    isRefresh: boolean = false,
  ): Promise<string> => {
    const waitTaskResult = async (): Promise<string> => {
      // 循环调用来查看状态结果
      let result = false
      let count = 0
      const maxCount = POLLING_TIMES // 最多轮询30次
      const waitTime = 2000
      let firstTime = true

      if (isRefresh) {
        await videoService.reloadBroadcastCopy(id)
      }
      while (!result && count < maxCount) {
        await sleep(firstTime ? 0 : waitTime)
        firstTime = false
        const res = await videoService.getBroadcastDetail(id)
        console.log('🚀 ~ getBroadcastDetail ~ res:', res)
        result = res.status === 'finish'
        const tipsWord = res.result?.msg ?? ''
        if (res.status.includes('error')) {
          toast({
            variant: 'destructive',
            title: '生成口播文案出错',
            description: `${res.status}: \n${tipsWord}`,
            duration: Infinity,
          })
          throw new Error('生成口播文案出错')
        }
        if (result) {
          // 就需要从头重试, 只重试1次
          // console.log('获取到结果了')
          return res.result.data
        }
        count++
      }
      return ''
    }
    let text = ''
    try {
      useLoadingStore.getState().increment()
      text = await waitTaskResult()
      // console.log('🚀 ~ getBroadcastDetail: ~ text:', text)
      set({ resText: text })
      useLoadingStore.getState().decrement()
    } catch (error) {
      console.error('🚀 ~ getBroadcastDetail: ~ error:', error)
      useLoadingStore.getState().decrement()
    }

    return text
  },
  // 轮询获取视频任务详情
  getAudioVideoDetail: async (id: string): Promise<string> => {
    const waitTaskResult = async (): Promise<string> => {
      // 循环调用来查看状态结果
      let result = false
      let count = 0
      const maxCount = POLLING_TIMES // 轮询次数
      const waitTime = 2000
      let firstTime = true
      while (!result && count < maxCount) {
        await sleep(firstTime ? 0 : waitTime)
        firstTime = false
        const res = await videoService.getAudioVideoDetail(id)
        console.log('🚀 ~ getBroadcastDetail ~ res:', res)
        const tipsWord = res.result.msg
        if (res.status.includes('error')) {
          useLoadingStore.getState().setLoadingMessage('')
          toast({
            variant: 'destructive',
            title: '生成口播视频出错',
            description: `${res.status}: \n${tipsWord}`,
            duration: Infinity,
          })
          throw new Error('生成口播视频出错' + res.status)
        }
        result = res.status === 'finish'
        // 文字状态

        useLoadingStore.getState().setLoadingMessage(tipsWord)
        set({ videoStatusInfo: tipsWord })
        console.log('🚀 ~ waitTaskResult ~ tipsWord:', tipsWord)
        if (result) {
          // 就需要从头重试, 只重试1次
          console.log('获取到结果了')
          return res.result.success_data.url
        }
        count++
      }
      return ''
    }
    useLoadingStore.getState().increment()
    let text = ''
    try {
      text = await waitTaskResult()
      console.log('🚀 ~ getBroadcastDetail: ~ text:', text)
      useLoadingStore.getState().decrement()
    } catch (error) {
      console.error('🚀 ~ getAudioVideoDetail: ~ error:', error)
      useLoadingStore.getState().decrement()
    }
    return text
  },
  // 历史记录
  getHistoryList: async (id: string) => {
    return await videoService.videoCreationDetail(id).then((res) => {
      console.log('res:', res)
    })
  },
}))

// 可选：创建一个自定义 hook 用于初始化数据
export const useInitVideoConfig = () => {
  const { fetchSystemConfig, fetchRegionList, fetchToneList, loading, error } =
    useVideoStore()

  // 使用之前写好的 useFetch 来处理初始化
  useFetch(
    async () => {
      await Promise.all([fetchSystemConfig(), fetchRegionList(), fetchToneList()])
    },
    {
      autoFetch: true,
    },
  )

  return { loading, error }
}

export interface CustomError extends Error {
  code?: string
}

type PollTaskOptions = {
  id: string
  getServiceDetail: (id: string) => Promise<any>
  reloadServiceCopy?: (id: string) => Promise<any>
  isRefresh?: boolean
  errorMessage?: string
  maxRetries?: number
  initialWaitTime?: number
  minWaitTime?: number
  decrementTime?: number
}
// 轮询获取任务结果
export async function pollingTaskResult({
  id,
  getServiceDetail,
  reloadServiceCopy,
  errorMessage = '发生了错误',
  isRefresh = false,
  maxRetries = POLLING_TIMES,
  initialWaitTime = 5000,
  minWaitTime = 2000,
  decrementTime = 2000,
}: PollTaskOptions): Promise<any> {
  if (isRefresh && !reloadServiceCopy) {
    throw new Error('当 isRefresh 为 true 时，必须提供 reloadServiceCopy 函数')
  }

  const waitTaskResult = async (): Promise<any> => {
    let result = false
    let count = 0
    let waitTime = isRefresh ? 0 : initialWaitTime

    if (isRefresh && reloadServiceCopy) {
      await reloadServiceCopy(id)
    }
    while (!result && count < maxRetries) {
      await sleep(waitTime)
      waitTime = Math.max(waitTime - decrementTime, minWaitTime)
      const res = await getServiceDetail(id)
      console.log('🚀 ~ getServiceDetail ~ res:', res)
      result = res.status === 'finish'
      if (res.status.includes('error')) {
        toast({
          variant: 'destructive',
          description: `${errorMessage} ${res.status}`,
          duration: Infinity,
        })
        // throw new Error(errorMessage)
        const cusError = new Error(errorMessage) as CustomError
        cusError['code'] = 'CUS_ERROR'
        throw cusError
      }
      if (result) {
        console.log('获取到结果了')
        return res.result.data
      }
      count++
    }
    return ''
  }
  let waitData = null
  try {
    useLoadingStore.getState().increment()
    waitData = await waitTaskResult()
  } catch (error: any) {
    console.error('🚀 ~ pollTaskResult: ~ error:', error)
    if (error?.code !== 'CUS_ERROR') {
      toast({
        variant: 'destructive',
        description: '出错了: ' + error,
        duration: Infinity, // 持续时间设置为无限大，直到手动关闭
      })
    }
  } finally {
    useLoadingStore.getState().decrement()
  }
  return waitData
}
